using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.Contracts;
using System.Linq;
using OpenWaves.ActivityFeed.Web.Modules;

namespace OpenWaves.ActivityFeed.Web.Controls
{
    [DefaultImplementation(typeof(ActivityFeedOptionsDtoBuilder))]
    public interface IActivityFeedOptionsDtoBuilder
    {
        ActivityFeedOptionsDto BuildActivityFeedOptionsDto(FeedType feedType, string customFeedTypeName, IEnumerable<Topic> topicsFilter, IEnumerable<Topic> newTopics,
            int pageSize, Collection<UpdateContentTemplate> updateContentTemplates,
            string onActivityFeedViewModelInitialize, string onUpdateViewModelInit);
    }

    public class ActivityFeedOptionsDtoBuilder : IActivityFeedOptionsDtoBuilder
    {
        private readonly IUserIdentityProvider userIdentityProvider;
        private readonly IActivityFeedService activityFeedService;
        private readonly IUserProfileProvider userProfileProvider;
        private readonly IUserGroupMembershipProvider groupMembershipProvider;
        private readonly IUpdateDtoBuilder updateDtoBuilder;

        public ActivityFeedOptionsDtoBuilder()
            : this(ServiceLocator.Resolve<IUserIdentityProvider>(), 
                    ServiceLocator.Resolve<IActivityFeedService>(), 
                    ServiceLocator.Resolve<IUserProfileProvider>(),
                    ServiceLocator.Resolve<IUserGroupMembershipProvider>(),
                    ServiceLocator.Resolve<IUpdateDtoBuilder>())
        {
        }

        public ActivityFeedOptionsDtoBuilder(IUserIdentityProvider userIdentityProvider, IActivityFeedService activityFeedService, IUserProfileProvider userProfileProvider,
            IUserGroupMembershipProvider groupMembershipProvider, IUpdateDtoBuilder updateDtoBuilder)
        {
            this.userIdentityProvider = userIdentityProvider;
            this.activityFeedService = activityFeedService;
            this.userProfileProvider = userProfileProvider;
            this.groupMembershipProvider = groupMembershipProvider;
            this.updateDtoBuilder = updateDtoBuilder;
        }

        public ActivityFeedOptionsDto BuildActivityFeedOptionsDto(FeedType feedType, string customFeedTypeName, IEnumerable<Topic> topicsFilter, IEnumerable<Topic> newTopics, int pageSize,
            Collection<UpdateContentTemplate> updateContentTemplates,
            string onActivityFeedViewModelInitialize, string onUpdateViewModelInit)
        {
            Contract.Requires<ArgumentNullException>(topicsFilter != null, "TopicsFilter have to be assigned");
            Contract.Requires<ArgumentNullException>(newTopics != null, "NewTopics have to be assigned");

            var activityFeedBuilder =
                ServiceLocator.Resolve<IActivityFeedBuilderFactory>().Create(feedType, customFeedTypeName, this.activityFeedService,
                                                                             this.updateDtoBuilder,
                                                                             this.userIdentityProvider.Identity.Name);
                
            activityFeedBuilder.PaginationRequest = new PaginationRequest { PageSize = pageSize };
            activityFeedBuilder.UserGroups = groupMembershipProvider.UserGroups;
            activityFeedBuilder.TopicsFilter = topicsFilter;

            PaginationStatus status;
            var activityFeedInitParameters = new ActivityFeedOptionsDto()
            {
                TopicsFilter = topicsFilter.Select(t => t.ToString()),
                NewTopics = newTopics.Select(t=>t.ToString()),
                User = UserDto.FromUserId(userIdentityProvider.Identity.Name, userProfileProvider),
                Updates = activityFeedBuilder.BuildActivityFeed(out status),
                IsListOfUpdatesComplete = status == PaginationStatus.CompleteResults,
                Source = "web",
                PageSize = pageSize,
                UpdateContentTemplates = updateContentTemplates.ToDictionary(template => template.ContentType, template => template.ClientID),
                FeedType = feedType,
                CustomFeedTypeName = customFeedTypeName,
                OnInitialize = onActivityFeedViewModelInitialize,
                OnUpdateViewModelInitialize = onUpdateViewModelInit
            };

            return activityFeedInitParameters;
        }
    }
}